#ifndef CPU_H
#define CPU_H

//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C" {
#endif

#ifndef __interrupt
#define __interrupt __attribute__((interrupt)) __attribute__((section(".text.interrupt.routine")))
#endif

#ifndef __clatask
#define __clatask __attribute__((clatask))
#endif

#ifndef __cpu2cla
#define __cpu2cla __attribute__((section(".cpu2cla_data")))
#endif

#ifndef __cla2cpu
#define __cla2cpu __attribute__((section(".cla2cpu_data")))
#endif

//
// Define to enable interrupts
//
#ifndef EINT
#define EINT                                                         \
    do                                                               \
    {                                                                \
        __asm__ volatile("nop||\n nop||\n jmp 2||\n nop||\n nop||"); \
        ExpRegs.INTM = 0;                                            \
    } while (0)
#endif

//
// Define to disable interrupts
//
#ifndef DINT
#define DINT (ExpRegs.INTM = 1)
#endif

//
// Define to enable debug events
//
#ifndef ERTM
#define ERTM // __asm(" clrc DBGM")
#endif

//
// Define to disable debug events
//
#ifndef DRTM
#define DRTM // __asm(" setc DBGM")
#endif

//
// Define to allow writes to protected registers
//
#ifndef EALLOW
#define EALLOW // __eallow()
#endif

//
// Define to disable writes to protected registers
//
#ifndef EDIS
#define EDIS // __edis()
#endif

//
// Define for emulation stop
//
#ifndef ESTOP0
#define ESTOP0 // __asm(" ESTOP0")
#endif

//
// Define for emulation stop
//
#ifndef ESTOP1
#define ESTOP1 // __asm(" ESTOP1")
#endif

//
// Define for no operation
//
#ifndef NOP
#define NOP __builtin_dsp_nop()
#endif

//
// Define for putting processor into a low-power mode
//
#ifndef IDLE
#define IDLE __builtin_dsp_idle_qx320f()
#endif

// clang-format off
#ifndef __QX_CLA_MODULE_START
#define __QX_CLA_MODULE_START _Pragma("clang section text=\".cla_text\" rodata=\".cla_rodata\" data=\".cla_data\" bss=\".cla_bss\"")
#endif

#ifndef __QX_CLA_MODULE_END
#define __QX_CLA_MODULE_END _Pragma("clang section text=\"\" rodata=\"\" data=\"\" bss=\"\"")
#endif
// clang-format on

extern void __eallow(void);
extern void __edis(void);

//*****************************************************************************
//
// Mark the end of the C bindings section for C++ compilers.
//
//*****************************************************************************
#ifdef __cplusplus
}
#endif

#endif // CPU_H
